<template>
  <div class="app-container">
    <div class="head-buttons">
      <el-button
        type="primary"
        size="mini"
        icon="el-icon-plus"
        @click="handleCreate"
      >新增菜单
      </el-button>
    </div>

    <el-table
      v-loading="listLoading"
      :data="list"
      :row-style="{height: '20px'}"
      highlight-current-row
      row-key="id"
      :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
    >
      <el-table-column label="菜单名称" prop="name" align="left" min-width="150px"/>
      <el-table-column label="菜单图标" prop="icon" align="center" width="80px">
        <template slot-scope="{row}">
          <svg-icon :icon-class="row.icon ? row.icon : ''"/>
        </template>
      </el-table-column>
      <el-table-column label="菜单路径" prop="path" align="left" width="100px"/>
      <el-table-column label="排序" prop="ordinal" align="center" width="50px"/>
      <el-table-column label="层级" prop="level" align="center" width="50px"/>
      <el-table-column label="创建时间" prop="createTime" align="center" width="150px"/>
      <el-table-column label="修改时间" prop="updateTime" align="center" width="150px"/>
      <el-table-column label="状态" align="center" fixed="right" class-name="status-col" width="50px">
        <template slot-scope="{row}">
          <el-switch
            @change="handleModifyStatus(row)"
            v-model="row.hide"
            :active-value="0"
            :inactive-value="1"
          >
          </el-switch>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" width="100px" fixed="right"
                       class-name="small-padding fixed-width"
      >
        <template slot-scope="{row}">
          <el-button class="table-btn" type="primary" icon="el-icon-edit" @click="handleUpdate(row)">
          </el-button>
          <el-button class="table-btn" type="danger" icon="el-icon-delete" @click="handleDelete(row)">
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-dialog
      :title="textMap[dialogStatus]"
      :visible.sync="dialogFormVisible"
      :close-on-click-modal="false"
      width="650px"
    >
      <el-form
        ref="formRef"
        class="dialog-from-margin"
        :rules="rules"
        status-icon
        :model="dataform"
        label-position="left"
        label-width="80px"
      >
        <el-form-item v-show="textMap[dialogStatus] === '新增'"
                      label="父级菜单" prop="parentId"
        >
          <el-popover
            ref="parent-popover"
            placement="bottom-start"
            width="530"
            trigger="click"
          >
            <el-tree :data="list" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
            <el-input slot="reference" v-model="parentName" clearable placeholder="请选择上级菜单/顶级菜单目录无需选择"></el-input>
          </el-popover>
        </el-form-item>
        <el-form-item label="菜单图标" prop="icon">
          <el-popover
            placement="bottom-start"
            width="530"
            trigger="click"
            @show="$refs['iconSelect'].reset()"
          >
            <IconSelect ref="iconSelect" @selected="selected"/>
            <el-input slot="reference" v-model="dataform.icon" placeholder="点击选择图标" readonly>
              <svg-icon
                v-if="dataform.icon"
                slot="prefix"
                :icon-class="dataform.icon"
                class="el-input__icon"
              />
              <i v-else slot="prefix" class="el-icon-search el-input__icon"/>
            </el-input>
          </el-popover>
        </el-form-item>
        <el-form-item label="菜单名称" prop="name">
          <el-input v-model="dataform.name" clearable maxlength="16" show-word-limit placeholder="请输入菜单名称"/>
        </el-form-item>
        <el-form-item label="菜单路径" prop="path">
          <el-input v-model="dataform.path" clearable placeholder="请输入菜单path"/>
        </el-form-item>
        <el-row :gutter="20">
          <el-col :span="12">

            <el-form-item label="状态" prop="hide">
              <el-switch
                v-model="dataform.hide"
                :active-value="0"
                :inactive-value="1"
                active-text="显示"
                inactive-text="隐藏"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="排序" prop="ordinal">
              <el-input-number v-model.number="dataform.ordinal" controls-position="right" :min="0" clearable/>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">
          取消
        </el-button>
        <el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">
          确定
        </el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
  import menu from '@/api/menu'
  import IconSelect from '@/components/IconSelect'
  import { getId } from '@/utils/auth'

  export default {
    name: 'Menu',
    components: { IconSelect },
    data () {
      return {
        list: [],
        defaultProps: {
          children: 'children',
          label: 'name',
        },
        listLoading: true,
        fullLoading: false,
        parentName: undefined,
        dataform: {
          id: undefined,
          name: undefined,
          parentId: 0,
          path: undefined,
          icon: undefined,
          ordinal: undefined,
          level: undefined,
          hide: undefined,
        },
        dialogFormVisible: false,
        dialogStatus: '',
        textMap: {
          update: '修改',
          create: '新增',
        },
        rules: {
          name: [
            { required: true, message: '请输入菜单名称', trigger: 'blur' },
            { max: 16, message: '长度必须小于16个字符', trigger: 'blur' },
          ],
          path: [
            { required: true, message: '请输入path', trigger: 'blur' },
          ],
          icon: [
            { required: true, message: '请选择图标', trigger: 'blur' },
          ],
          ordinal: [
            { required: true, message: '请输入排序顺序', trigger: 'blur' },
            { type: 'number', message: '排序顺序只支持数值', trigger: 'blur' },
          ],
          level: [
            { required: true, message: '请输入level', trigger: 'blur' },
            { type: 'number', message: '排序顺序只支持数值', trigger: 'blur' },
          ],
          hide: [
            { required: true, message: '请选择状态', trigger: 'blur' },
          ],
        },
      }
    },
    created () {
      this.getList()
      // const data = JSON.parse(JSON.stringify(this.$store.state.menu.menus))//深拷贝菜单menus,为了数据修改不影响menus
      // this.list=data////父菜单隐藏所有子菜单列表不隐藏
      // this.list = this.filterTree(data)//父菜单隐藏所有子菜单列表隐藏
      this.listLoading = false
    },
    methods: {
      // 获取图标名称
      selected (name) {
        this.dataform.icon = name
      },
      // 获取列表
      async getList () {
        this.listLoading = true
        const adminId = 'adminId=' + getId()
        let { data, code } = await menu.getMenu(adminId)
        if (code === 200) {
          await this.$store.dispatch('menu/setMenu', data)
          this.list = data////父菜单隐藏所有子菜单列表不隐藏
          // this.list = this.filterTree(data)//父菜单隐藏所有子菜单列表隐藏
        }
        this.listLoading = false
      },
      resetTemp () {
        this.dataform = {
          id: undefined,
          name: undefined,
          parentId: 0,
          path: undefined,
          icon: 'example',
          ordinal: 0,
          level: undefined,
          hide: undefined,
        }
      },
      // 选择父亲菜单
      handleNodeClick (data) {
        this.$refs['parent-popover'].showPopper = false
        this.parentName = data.name
        this.dataform.parentId = data.id
      },
      filterTree (list) {//对tree进行筛选，hide=false的儿子不显示在菜单
        return list.map((obj) => {
          if (obj.hide === 0 && obj.children.length > 0) {
            obj.children = this.filterTree(obj.children)
            return obj
          }
          if (obj.hide === 1 && obj.children.length > 0) {
            obj.children = []
            return obj
          }
          return obj
        })
      },
      // 切换状态 是否隐藏
      async handleModifyStatus (row) {
        this.dataform = Object.assign({}, row) // copy obj
        delete this.dataform.children
        await menu.updateMenu(this.dataform.id, this.dataform)
        this.$message.success('更新成功')
        this.getList()
      },
      // 打开添加菜单对话框
      handleCreate () {
        this.resetTemp()
        this.parentName = '主菜单'
        this.dialogStatus = 'create'
        this.dialogFormVisible = true
        this.$nextTick(() => {
          // 重新加载菜单数据
          this.$refs['formRef'].clearValidate()
        })
      },
      // 添加菜单
      createData () {
        let data = { ...this.dataform }
        delete data['id']//暂时删除不必要字段
        delete data['level']
        this.$refs['formRef'].validate(async(valid) => {
          if (valid) {
            this.fullLoading = true
            await menu.createMenu(this.dataform)
            this.fullLoading = false
            this.dialogFormVisible = false
            this.$message.success('添加成功')
            this.getList()
          }
        })
      },
      // 打开更新菜单对话框
      handleUpdate (row) {
        this.dataform = Object.assign({}, row) // copy obj
        delete this.dataform.children
        this.dialogStatus = 'update'
        this.dialogFormVisible = true
        this.$nextTick(() => {
          // 重新加载菜单数据
          this.$refs['formRef'].clearValidate()
        })
      },
      // 更新菜单
      updateData () {
        this.$refs['formRef'].validate(async(valid) => {
          if (valid) {
            this.fullLoading = true
            await menu.updateMenu(this.dataform.id, this.dataform)
            this.fullLoading = false
            this.dialogFormVisible = false
            this.$message.success('更新成功')
            this.getList()

          }
        })
      },
      // 删除菜单
      handleDelete (row) {
        this.$confirm('删除该记录，如果当前记录下包含子节点请先删除子节点，是否继续删除？', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        }).then(async() => {
          this.fullLoading = true
          await menu.deleteMenu(row.id)
          this.fullLoading = false
          this.$message.success('删除成功')
          this.getList()
        }).catch(() => {
          this.$message.info('删除取消！')
        })
      },
    },
  }
</script>

<style lang="scss" scoped>
.head-buttons {
  display: flex;
  justify-content: flex-start;
  margin-bottom: 10px;
}

::v-deep .el-table {
  th {
    padding: 0;
  }

  td {
    padding: 0;
  }
}

.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 16px;
  padding-right: 8px;
  letter-spacing: 1px;
}

.table-btn {
  margin: 1px 5px;
  padding: 5px;
}
</style>
